#include <iostream>
#include <sys/types.h>
#include <cstdio>
#include <cerrno>
#include <sys/socket.h>
#include <arpa/inet.h>
#include <string>
void Usage(std::string port)
{
    std::cout << "Usage:\n\t"
              << port << " port" << std::endl;
}
int main(int argc, char* argv[])
{
    if (argc != 2)
    {
        Usage(argv[0]);
        return 1;
    }
    const uint16_t port = atoi(argv[1]);
    // 1.创建套接字
    int sock = socket(AF_INET, SOCK_DGRAM, 0);
    if (sock < 0)
    {
        std::cerr << "socket create fail:" << errno << std::endl;
        return 1;
    }
    // 2.绑定套接字

    struct sockaddr_in local;
    local.sin_family = AF_INET;
    local.sin_port = htons(port);
    // 云服务器不允许用户直接bind，云服务器有多个ip
    // local.sin_addr.s_addr = inet_addr("101.33.218.152");
    local.sin_addr.s_addr = INADDR_ANY;
    if (bind(sock, (struct sockaddr *)&local, sizeof(local)) < 0)
    {
        std::cerr << "socket bind fail:" << errno << std::endl;
        return 2;
    }
    // 3.提供服务
    bool quit = false;
    char buffer[1024];
    while (!quit)
    {
        struct sockaddr_in peer;
        socklen_t len = sizeof(peer);
        ssize_t cnt = recvfrom(sock, buffer, sizeof(buffer) - 1, 0, (struct sockaddr *)&peer, &len);
        std::cout << "client# " << buffer << std::endl;
        if (cnt > 0)
        {
            buffer[cnt] = 0;
            FILE* fp = popen(buffer,"r");
            std::string echo_hello = buffer;
            char line[1024] = {0};
            while(fgets(line,sizeof(line),fp))
            {
                echo_hello += line;
            }
            fclose(fp);
            sendto(sock, echo_hello.c_str(), echo_hello.size(), 0, (struct sockaddr *)&peer, len);
        }
    }
    return 0;
}